/**
* 标准收发器
*/

#define _CRT_SECURE_NO_WARNINGS
#include <stdint.h>

#include "utils.h"
#include "transceiver.h"

std_err_t rx_ret_to_std_err(rx_ret_t ret) {
	if (ret <= RX_RET_ERROR)    return (std_err_t)ret;
	if (ret == RX_RET_FULL)     return STD_ERR_BUFFER_OVERFLOW;
	if (ret == RX_RET_TIMEOUT)  return STD_ERR_TIMEOUT;
	if (ret == RX_RET_INTERVAL) return STD_ERR_INTERVAL_TIMEOUT;
	if (ret == RX_RET_OK)       return STD_ERR_OK;
	if (ret == RX_RET_FAIL)     return STD_ERR_INVALID_RESPONSE;
	if (ret == RX_RET_ALL)      return STD_ERR_OK;
	return STD_ERR_FAIL;
}

const char* rx_ret_comment(rx_ret_t ret) {
	switch(ret) {
	case RX_RET_FULL:     return "RX_RET_FULL";
	case RX_RET_TIMEOUT:  return "RX_RET_TIMEOUT";
	case RX_RET_INTERVAL: return "RX_RET_INTERVAL";
	case RX_RET_OK:       return "RX_RET_OK";
	case RX_RET_FAIL:     return "RX_RET_FAIL";
	case RX_RET_ALL:      return "RX_RET_ALL";
	default: return std_err_comment(ret);
	}
}

static size_t _dummy_get_mtu(struct _transceiver* ifdev) { return 65536; }
static std_err_t _dummy_clear_rx_buffer(struct _transceiver* ifdev) { return STD_ERR_OK; }
static rx_ret_t _dummy_rx(struct _transceiver *ifdev, void* buf, size_t size, size_t *len, long timeout, /*long lead,*/ long interval, const char *okFlag, rx_flag_t okFlagType, const char *failFlag, rx_flag_t failFlagType) { return RX_RET_TIMEOUT; }
static std_err_t _dummy_rxline(struct _transceiver *ifdev, void* buf, size_t size, size_t *len) { return STD_ERR_OK; }
static std_err_t _dummy_tx(struct _transceiver *ifdev, const void* buf, size_t size, size_t *len) { return STD_ERR_OK; }
static void _dummy_close(struct _transceiver* ifdev) { if(ifdev) free(ifdev); }

transceiver_t* transceiver_open_dummy(const char* addr) {
	transceiver_t *trx = MALLOC0(transceiver_t);
	if (!trx) return NULL;
	trx->hif = trx;
	trx->get_mtu = _dummy_get_mtu;
	trx->clear_rx_buffer = _dummy_clear_rx_buffer;
	trx->rx = _dummy_rx;
	trx->rxline = _dummy_rxline;
	trx->tx = _dummy_tx;
	trx->close = _dummy_close;
	return trx;
}

rx_ret_t transceiver_cmdack(transceiver_t *trx, const char *cmd, char *rxbuf, size_t rxbuf_size, long timeout, const char *okFlag, const char *failFlag) {
    // 清除接收缓冲区
    trx->clear_rx_buffer(trx);
    
	// 发送指令
    std_err_t err = trx->tx(trx, cmd, strlen(cmd), NULL);
    if(err) return (rx_ret_t)err;

    // 接收返回数据
    size_t dlen = 0;
	rx_flag_t okFlagType = RX_FLAG_STRING, failFlagType = RX_FLAG_STRING;
	if(okFlag   && okFlag[0]   == '@') { okFlagType   = RX_FLAG_REGEXP; okFlag++;   }
	if(failFlag && failFlag[0] == '@') { failFlagType = RX_FLAG_REGEXP; failFlag++; }
    rx_ret_t ret = trx->rx(trx, rxbuf, rxbuf_size, &dlen, timeout, -1, okFlag, okFlagType, failFlag, failFlagType);
    rxbuf[dlen] = '\0';
    return ret;
}

/// @brief 做为标准 I/O 的收发器
static transceiver_t* _stdtrx = NULL;

transceiver_t* transceiver_set_std(transceiver_t* trx) {
    transceiver_t* old = _stdtrx;
    _stdtrx = trx;
    return old;
}

transceiver_t* transceiver_get_std() {
    return _stdtrx;
}
